package com.ghy.service.impl;

import cn.hutool.core.bean.BeanUtil;

import cn.hutool.core.util.ObjectUtil;

import com.ghy.dto.OrderDetailInsertDTO;
import com.ghy.dto.OrderDetailPageDTO;
import com.ghy.dto.OrderDetailUpdateDTO;
import com.ghy.entity.*;
import com.ghy.entity.OrderDetail;
import com.ghy.excel.OrderDetailExcelDTO;
import com.ghy.exception.ServiceException;
import com.ghy.feign.CourseFeign;
import com.ghy.feign.UserFeign;
import com.ghy.mapper.OrderMapper;
import com.ghy.vo.OrderDetailSimpleListVO;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.relation.RelationManager;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;

import com.ghy.mapper.OrderDetailMapper;
import com.ghy.service.OrderDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;


import java.time.LocalDateTime;
import java.util.ArrayList;

import java.util.List;

import static com.ghy.entity.table.OrderDetailTableDef.ORDER_DETAIL;
import static com.ghy.entity.table.OrderTableDef.ORDER;


/**
 * 订单明细表 服务层实现。
 *
 * @author ghy
 * @since 2024-12-22
 */
@Service
@CacheConfig(cacheNames = "order")
public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail>  implements OrderDetailService{
    @Autowired
    private CourseFeign courseFeign;

    @Autowired
    private OrderMapper orderMapper;

    @CacheEvict(allEntries = true)
    @Override
    public boolean insert(OrderDetailInsertDTO dto) {
        // 组装 entity 实体类
        OrderDetail orderDetail = BeanUtil.copyProperties(dto, OrderDetail.class);
        Course course = courseFeign.select(dto.getFkCourseId()).getData();
        //秒杀ID和课程ID的组合查重
        if(QueryChain.of(mapper)
                .where(ORDER_DETAIL.FK_ORDER_ID.eq(dto.getFkOrderId()))
                .and(ORDER_DETAIL.FK_COURSE_ID.eq(dto.getFkCourseId()))
                .exists()){
            throw new ServiceException("订单明细已存在") ;
        }
        if(ObjectUtil.isNull(course)){
            throw new RuntimeException("课程不存在");
        }
        // 使用 QueryChain 检查订单是否存在
        boolean orderExists = QueryChain.of(orderMapper)
                .where(ORDER.ID.eq(dto.getFkOrderId()))
                .exists();

        if (!orderExists) {
            throw new ServiceException("订单不存在");
        }
        orderDetail.setCourseTitle(course.getTitle());
        orderDetail.setCourseCover(course.getCover());
        orderDetail.setCoursePrice(course.getPrice());
        orderDetail.setCreated(LocalDateTime.now());
        orderDetail.setUpdated(LocalDateTime.now());
        return mapper.insert(orderDetail) > 0;
    }

    @Cacheable(key = "'detail:' + #p0", condition = "#p0 != null", unless = "#result == null")
    @Override
    public OrderDetail select(Long id) {
        RelationManager.addQueryRelations("course", "order");
        return mapper.selectOneWithRelationsById(id);
    }

    @Override
    @Cacheable(key = "'detail:' + #root.methodName", unless = "#result == null")
    public List<OrderDetailSimpleListVO> simpleList() {
        return QueryChain.of(mapper)
                .orderBy(ORDER_DETAIL.ID.desc())
                .withRelations()
                .listAs(OrderDetailSimpleListVO.class);
    }

    @Cacheable(key = "'detail:' + #root.methodName + ':' + #p0.toString()", condition = "#p0 != null", unless = "#result == null")
    @Override
    public Page<OrderDetail> page(OrderDetailPageDTO dto) {
        RelationManager.addQueryRelations("course", "order");
        QueryChain<OrderDetail> queryChain = QueryChain.of(mapper)
                .orderBy(ORDER_DETAIL.ID.desc());
        return queryChain.withRelations()
                .page(new Page<>(dto.getPageNum(), dto.getPageSize()));
    }

    @Override
    public List<OrderDetailExcelDTO> excel() {
        // 查询全部订单明细记录
        List<OrderDetail> orderDetails = QueryChain.of(mapper).list();

        // 转换为 List<OrderDetailExcelDTO>
        List<OrderDetailExcelDTO> result = new ArrayList<>();
        orderDetails.forEach(orderDetail -> {
            // 拷贝订单明细基础信息
            OrderDetailExcelDTO orderDetailExcelDTO = BeanUtil.copyProperties(orderDetail, OrderDetailExcelDTO.class);

            // 使用 QueryChain 获取订单信息
            Order order = QueryChain.of(orderMapper)
                    .select(ORDER.SN, ORDER.STATUS, ORDER.INFO, ORDER.PAY_AMOUNT, ORDER.PAY_TYPE)
                    .where(ORDER.ID.eq(orderDetail.getFkOrderId()))
                    .one();

            if (order != null) {
                orderDetailExcelDTO.setSn(order.getSn()); // 订单编号
                orderDetailExcelDTO.setStatus(order.getStatus() + ""); // 订单状态
                orderDetailExcelDTO.setInfo(order.getInfo()); // 订单描述
                orderDetailExcelDTO.setPayAmount(order.getPayAmount()); // 实际支付总金额
                orderDetailExcelDTO.setPayType(order.getPayType() + ""); // 订单支付方式
                orderDetailExcelDTO.setUsername(order.getUsername()); // 下单账号
            }
            result.add(orderDetailExcelDTO);
        });
        return result;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(OrderDetailUpdateDTO dto) {
        // 组装 entity 实体类
        OrderDetail orderDetail = BeanUtil.copyProperties(dto, OrderDetail.class);
        Course course = courseFeign.select(dto.getFkCourseId()).getData();
        //秒杀ID和课程ID的组合查重
        if(QueryChain.of(mapper)
                .where(ORDER_DETAIL.FK_ORDER_ID.eq(dto.getFkOrderId()))
                .and(ORDER_DETAIL.FK_COURSE_ID.eq(dto.getFkCourseId()))
                .exists()){
            throw new ServiceException("订单明细已存在") ;
        }
        if(ObjectUtil.isNull(course)){
            throw new RuntimeException("课程不存在");
        }
        // 使用 QueryChain 检查订单是否存在
        boolean orderExists = QueryChain.of(orderMapper)
                .where(ORDER.ID.eq(dto.getFkOrderId()))
                .exists();

        if (!orderExists) {
            throw new ServiceException("订单不存在");
        }
        orderDetail.setCourseTitle(course.getTitle());
        orderDetail.setCourseCover(course.getCover());
        orderDetail.setCoursePrice(course.getPrice());
        orderDetail.setUpdated(LocalDateTime.now());
        return UpdateChain.of(orderDetail)
                .where(ORDER_DETAIL.ID.eq(orderDetail.getId()))
                .update();
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean delete(Long id) {
        return mapper.deleteById(id) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteBatch(List<Long> ids) {
        return mapper.deleteBatchByIds(ids) > 0;
    }

}